package com.bbc.stock;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Properties;
import java.util.Random;
import java.util.logging.FileHandler;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import br.com.bb.provider.InformationProvider;
import br.com.bb.stock.Stock;

public class BBC implements InformationProvider {

	private String name;
	private NumberFormat df = DecimalFormat.getInstance(Locale.US);
	private String driver;
	private String url;
	private Properties config;
	private int launch;
	private int count;
	private Logger logger;
	private FileHandler fh;
	private Formatter formatter;

	// private ComboPooledDataSource cpds;

	private Connection getConnection() throws SQLException {
		// return cpds.getConnection();
		return DriverManager.getConnection("proxool.agencia:" + driver + ":" + url,config);
	}

	public BBC() throws SecurityException, IOException {
		this.logger  = Logger.getLogger("LoggerService");
		this.logger.setUseParentHandlers(false);
		this.formatter = new Formatter() {
			@Override
			public String format(LogRecord record) {
				StringBuilder builder = new StringBuilder(1000);
				builder.append(formatMessage(record));
				builder.append("\n");
				return builder.toString();
			}
		};
		
		this.fh = new FileHandler("logProcessingTime.txt");
		this.fh.setFormatter(this.formatter);
		this.fh.setFilter(new Filter() {
			public boolean isLoggable(LogRecord record) {
				String msg = record.getMessage();
				if (msg.startsWith("ProcessingTime")) {
					return true;		
				}
				return false;
			}
		});
		this.logger.addHandler(fh);
		this.name            = "BBC";
		this.driver          = "org.apache.derby.jdbc.ClientDriver";
		this.count           = 0;
		//this.url             = "jdbc:derby://192.168.1.2:1527/Database/InformationProviderBbcDB;traceFile=trace.log";
		this.url             = "jdbc:derby://localhost/Database/InformationProviderBbcDB;traceFile=trace.log";
		try {
			Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.config = new Properties();
		config.setProperty("proxool.maximum-connection-count", "100");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getCotation(Stock stock) {
		long start = System.currentTimeMillis();
		Connection conn = null;
		PreparedStatement psSelectCotacao = null;
		PreparedStatement psUpdateCotacao = null;
		double result = 0;
		double cotation = 0;

		try {
			conn = this.getConnection();
			// System.out.println("Connected to database " + DB_CONNECTION_URL);
			psSelectCotacao = conn
					.prepareStatement("SELECT STK_PRICE FROM STK_STOCK WHERE STK_CODE = ?");

			psSelectCotacao.setString(1, stock.getCode());
			ResultSet cotationRS = psSelectCotacao.executeQuery();
			if (cotationRS.next()) {
				cotation = cotationRS.getDouble(1);
			}
			result = Double.valueOf(df.format(cotation));
			System.out.println(("=====>> " + this.getName()+ ": " + stock.getCode() + " - " + stock.getName() + ": " + result));
			Random random = new Random();
			boolean isPositive = random.nextBoolean();
			double variation = 0.05 * random.nextDouble();
			if (isPositive) {
				cotation = cotation + variation;
			} else {
				cotation = cotation - variation;
			}
			cotation = Double.valueOf(df.format(cotation));
			psUpdateCotacao = conn
					.prepareStatement("UPDATE STK_STOCK SET STK_PRICE = ? WHERE STK_CODE = ?");
			psUpdateCotacao.setDouble(1, cotation);
			psUpdateCotacao.setString(2, stock.getCode());
			psUpdateCotacao.executeUpdate();
			
		} catch (Throwable e) {
			e.printStackTrace();
		} finally {
			if (psSelectCotacao != null) {
				try {
					psSelectCotacao.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (psUpdateCotacao != null) {
				try {
					psUpdateCotacao.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

		}
		StringBuilder builder = new StringBuilder(1000);
		builder.append("ProcessingTime").append(" - ");
		builder.append(System.currentTimeMillis()- start);
		logger.log(Level.INFO, builder.toString());
		return result;
	}
	
	public static void main(String[] args) throws SecurityException, IOException {
		BBC bbc = new BBC();
		System.out.println("Cotacao PETR3: " + bbc.getCotation(Stock.BB3));
	}

}
